#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from twisted.web import resource
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
import json
import uuid
from utility import tools
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class GameWebSocketProtocol(WebSocketServerProtocol):
    def __init__(self):
        super().__init__()
        self.user_id = None
        self.authenticated = False

    def onConnect(self, request):
        logging.info(f"WebSocket连接请求来自: {request.peer}")

    def onOpen(self):
        logging.info("WebSocket连接已打开")

    def onMessage(self, payload, isBinary):
        if not isBinary:
            try:
                message = json.loads(payload.decode('utf8'))
                self.handle_message(message)
            except json.JSONDecodeError:
                self.send_error("Invalid JSON format")
        else:
            self.send_error("Binary messages not supported")

    def handle_message(self, message):
        action = message.get('action')

        # 处理认证请求
        if action == 'authenticate':
            self.authenticate(message)
            return

        # 检查是否已经认证
        if not self.authenticated:
            self.send_error("Authentication required")
            return

        # 处理各种游戏操作
        if action == 'move':
            self.handle_move(message)
        elif action == 'get_items':
            self.handle_get_items()
        elif action == 'add_item':
            self.handle_add_item(message)
        else:
            self.send_error(f"Unknown action: {action}")

    def authenticate(self, message):
        # 这里实现与短连接相同的token验证逻辑
        token = message.get('token')
        user_id = message.get('user_id')

        # 示例验证逻辑（应与现有系统保持一致）
        if self.factory.validate_token(token, user_id):
            self.authenticated = True
            self.user_id = user_id
            self.factory.register_user(user_id, self)
            self.send_success("Authentication successful")
        else:
            self.send_error("Authentication failed")
            # 可以选择关闭连接
            # self.sendClose()

    def handle_move(self, message):
        direction = message.get('direction')
        if not direction:
            self.send_error("Direction required")
            return

        # 更新玩家位置
        user_data = self.factory.game_state.users.get(self.user_id)
        if not user_data:
            self.factory.game_state.users[self.user_id] = {'x': 0, 'y': 0, 'inventory': []}
            user_data = self.factory.game_state.users[self.user_id]

        if direction == 'up':
            user_data['y'] += 10
        elif direction == 'down':
            user_data['y'] -= 10
        elif direction == 'left':
            user_data['x'] -= 10
        elif direction == 'right':
            user_data['x'] += 10

        response = {
            'action': 'position_update',
            'position': user_data
        }
        response = tools.dict_snake_case_to_camel(response)
        self.sendMessage(json.dumps(response).encode('utf8'))

    def handle_get_items(self):
        user_data = self.factory.game_state.users.get(self.user_id, {})
        inventory = user_data.get('inventory', [])

        response = {
            'action': 'items_list',
            'items': inventory
        }
        self.sendMessage(json.dumps(response).encode('utf8'))

    def handle_add_item(self, message):
        item_data = message.get('item', {})
        item_name = item_data.get('name')
        item_type = item_data.get('type')

        if not item_name:
            self.send_error("Item name required")
            return

        user_data = self.factory.game_state.users.get(self.user_id)
        if not user_data:
            self.factory.game_state.users[self.user_id] = {'x': 0, 'y': 0, 'inventory': []}
            user_data = self.factory.game_state.users[self.user_id]
        elif 'inventory' not in user_data:
            user_data['inventory'] = []

        new_item = {
            'name': item_name,
            'type': item_type,
            'id': len(user_data['inventory']) + 1
        }
        user_data['inventory'].append(new_item)

        response = {
            'action': 'item_added',
            'item': new_item
        }
        response = tools.dict_snake_case_to_camel(response)
        self.sendMessage(json.dumps(response).encode('utf8'))

    def send_success(self, message):
        response = {
            'code': 0,
            'msg': message
        }
        self.sendMessage(json.dumps(response).encode('utf8'))

    def send_error(self, message):
        response = {
            'code': 100,
            'msg': message
        }
        self.sendMessage(json.dumps(response).encode('utf8'))

    def onClose(self, wasClean, code, reason):
        logging.info(f"WebSocket连接关闭: {reason}")
        if self.user_id:
            self.factory.unregister_user(self.user_id)

class GameWebSocketFactory(WebSocketServerFactory):
    def __init__(self, game_state):
        super().__init__()
        self.game_state = game_state
        self.users = {}  # user_id -> protocol mapping
        self.tokens = {}   # Simple token storage for demo

    def register_user(self, user_id, protocol):
        self.users[user_id] = protocol
        logging.info(f"Player {user_id} registered with WebSocket")

    def unregister_user(self, user_id):
        if user_id in self.users:
            del self.users[user_id]
            logging.info(f"Player {user_id} unregistered from WebSocket")

    def validate_token(self, token, user_id):
        # 这里应该实现与现有系统相同的token验证逻辑
        # 示例实现 - 实际项目中应该使用更安全的方法
        if not token or not user_id:
            return False

        # 检查token是否有效
        if token in self.tokens and self.tokens[token] == user_id:
            return True

        # 或者实现更复杂的验证逻辑
        # 例如检查数据库中的token等
        return True  # 简化示例，总是返回True

    def issue_token(self, user_id):
        # 为玩家生成token
        token = str(uuid.uuid4())
        self.tokens[token] = user_id
        return token

    def broadcast_to_user(self, user_id, message):
        """向特定玩家发送消息"""
        if user_id in self.users:
            self.users[user_id].sendMessage(json.dumps(message).encode('utf8'))

    def broadcast_all(self, message):
        """广播消息给所有连接的玩家"""
        for protocol in self.users.values():
            protocol.sendMessage(json.dumps(message).encode('utf8'))

# WebSocket资源类
class WebSocketResource(resource.Resource):
    isLeaf = True

    def __init__(self, game_state):
        super().__init__()
        self.game_state = game_state
        self.ws_factory = GameWebSocketFactory(game_state)

    def render_GET(self, request):
        # 返回WebSocket连接信息
        from cors_middleware import CorsResource
        cors = CorsResource()
        cors._set_cors_headers(request)

        response = {
            'code': 0,
            'msg': 'WebSocket endpoint',
            'data': {
                'endpoint': 'ws://localhost:8080/websocket'
            }
        }
        request.setHeader(b'Content-Type', b'application/json')
        return json.dumps(response).encode('utf8')

    def get_ws_factory(self):
        return self.ws_factory
